#include "stdafx.h"
#include "Container.h"

#include <vector>
#include <iostream>
#include <algorithm>

// Test the vector container's assign operation
void VectorAssignAction(void)
{
	// TODO: it will cause a compiler error
	//std::cout << __func__ << std::endl;

	std::vector<int> v1(10, 2);
	// Print v1
	std::for_each (std::begin(v1), std::end(v1), [&](const int& it) { std::cout << it << " "; });
	std::cout << std::endl;

	std::cout << "After assign operation" << std::endl;
	std::vector<int> v2 = v1;
	// Print v2
	std::for_each (std::begin(v2), std::end(v2), [&](const int& it) { std::cout << it << " "; });
	std::cout << std::endl;

	// Change v2's value
	// It's a good case to study the value and reference for vector
	// it's bad since it pass a v2 value to the lambda body, so you 
	// always get the same sum value
	int index(1);
	std::generate(std::begin(v2) + 2, std::end(v2), [=]() mutable { int tmp = index + 1; index = tmp;
	int n = v2.at(index - 1) + v2.at(index - 2);
	return n; });
	std::cout << std::endl;

	// Print v1
	std::for_each (std::begin(v1), std::end(v1), [&](const int& it) { std::cout << it << " "; });
	std::cout << std::endl;
	// Print v2
	std::for_each (std::begin(v2), std::end(v2), [&](const int& it) { std::cout << it << " "; });
	std::cout << std::endl;

	/// It's also a copy constructor against v2
	//index = 1;
	//std::generate(std::begin(v2) + 2, std::end(v2), [&index, v2]() { ++index;
	//int n = v2.at(index - 1) + v2.at(index - 2);
	//return n; });
	//std::cout << std::endl;

		// Print v1
	std::for_each (std::begin(v1), std::end(v1), [&](const int& it) { std::cout << it << " "; });
	std::cout << std::endl;
	// Print v2
	std::for_each (std::begin(v2), std::end(v2), [&](const int& it) { std::cout << it << " "; });
	std::cout << std::endl;

	// Bellow get a good casue
	// Recap:
	// Make sure the captured variable has the correct reference/value type in the lambda body
	// It's import since it can cause some logic error and find it out hardly.
	index = 1;
	std::generate(std::begin(v2) + 2, std::end(v2), [=, &v2]() mutable { int tmp = index + 1; index = tmp;
	int n = v2.at(index - 1) + v2.at(index - 2);
	return n; });
	std::cout << std::endl;

	// Print v1
	std::for_each (std::begin(v1), std::end(v1), [&](const int& it) { std::cout << it << " "; });
	std::cout << std::endl;
	// Print v2
	std::for_each (std::begin(v2), std::end(v2), [&](const int& it) { std::cout << it << " "; });
	std::cout << std::endl;

	std::cout << std::endl;
}



// Reference:
// http://msdn.microsoft.com/en-us/library/windows/apps/hh438479.aspx